/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.mybatis.ext.sql;

import java.util.Collection;
import java.util.function.Consumer;
import org.elsfs.cloud.common.mybatis.ext.sql.support.builder.StandardSelectSql;

/**
 * 可选择接口
 *
 * @param <C> 子类实现
 */
@SuppressWarnings("unchecked")
public interface Selectable<C extends Selectable<C>> {

  /**
   * 选择SQL字段
   *
   * @param fields SQL字段名称
   * @return 具体实现
   */
  C select(String... fields);

  /**
   * 选择SQL字段
   *
   * @param fields SQL字段枚举
   * @return 具体实现
   */
  C select(Enum<?>... fields);

  /**
   * 选择SQL字段
   *
   * @param fields SQL字段
   * @return 具体实现
   */
  C select(Collection<String> fields);

  /**
   * 选择SQL字段
   *
   * @param condition 条件
   * @param fields SQL字段
   * @return 具体实现
   */
  default C select(boolean condition, String... fields) {
    if (condition) {
      return this.select(fields);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段
   *
   * @param condition 条件
   * @param fields SQL字段枚举
   * @return 具体实现
   */
  default C select(boolean condition, Enum<?>... fields) {
    if (condition) {
      return this.select(fields);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段
   *
   * @param condition 条件
   * @param fields SQL字段
   * @return 具体实现
   */
  default C select(boolean condition, Collection<String> fields) {
    if (condition) {
      return this.select(fields);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段表达式
   *
   * @param expressions SQL字段表达式
   * @return 具体实现
   */
  C selectExpression(String... expressions);

  /**
   * 选择SQL字段表达式
   *
   * @param expressions SQL字段表达式
   * @return 具体实现
   */
  C selectExpression(Collection<String> expressions);

  /**
   * 选择SQL字段表达式
   *
   * @param condition 条件
   * @param expressions SQL字段表达式
   * @return 具体实现
   */
  default C selectExpression(boolean condition, String... expressions) {
    if (condition) {
      return this.selectExpression(expressions);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段表达式
   *
   * @param condition 条件
   * @param expressions SQL字段表达式
   * @return 具体实现
   */
  default C selectExpression(boolean condition, Collection<String> expressions) {
    if (condition) {
      return this.selectExpression(expressions);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段
   *
   * @param field SQL字段
   * @param fieldAlias 字段别名
   * @return 具体实现
   */
  C selectAs(String field, String fieldAlias);

  /**
   * 选择SQL字段
   *
   * @param field SQL字段枚举
   * @param fieldAlias 字段别名
   * @return 具体实现
   */
  C selectAs(Enum<?> field, String fieldAlias);

  /**
   * 选择SQL字段
   *
   * @param field SQL字段枚举
   * @param fieldAlias 字段别名枚举
   * @return 具体实现
   */
  C selectAs(Enum<?> field, Enum<?> fieldAlias);

  /**
   * 选择子查询结果
   *
   * @param sqlBuilderConsumer SQL构建器消费器
   * @param fieldAlias 字段别名
   * @return 具体实现
   */
  C selectAs(Consumer<StandardSelectSql> sqlBuilderConsumer, String fieldAlias);

  /**
   * 选择子查询结果
   *
   * @param sqlBuilderConsumer SQL构建器消费器
   * @param fieldAlias 字段别名枚举
   * @return 具体实现
   */
  C selectAs(Consumer<StandardSelectSql> sqlBuilderConsumer, Enum<?> fieldAlias);

  /**
   * 选择SQL字段
   *
   * @param condition 条件
   * @param field SQL字段枚举
   * @param fieldAlias 字段别名
   * @return 具体实现
   */
  default C selectAs(boolean condition, Enum<?> field, String fieldAlias) {
    if (condition) {
      return this.selectAs(field, fieldAlias);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段
   *
   * @param condition 条件
   * @param field SQL字段枚举
   * @param fieldAlias 字段别名枚举
   * @return 具体实现
   */
  default C selectAs(boolean condition, Enum<?> field, Enum<?> fieldAlias) {
    if (condition) {
      return this.selectAs(field, fieldAlias);
    }

    return (C) this;
  }

  /**
   * 选择子查询结果
   *
   * @param condition 条件
   * @param sqlBuilderConsumer SQL构建器消费器
   * @param fieldAlias 字段别名
   * @return 具体实现
   */
  default C selectAs(
      boolean condition, Consumer<StandardSelectSql> sqlBuilderConsumer, String fieldAlias) {
    if (condition) {
      return this.selectAs(sqlBuilderConsumer, fieldAlias);
    }

    return (C) this;
  }

  /**
   * 选择子查询结果
   *
   * @param condition 条件
   * @param sqlBuilderConsumer SQL构建器消费器
   * @param fieldAlias 字段别名枚举
   * @return 具体实现
   */
  default C selectAs(
      boolean condition, Consumer<StandardSelectSql> sqlBuilderConsumer, Enum<?> fieldAlias) {
    if (condition) {
      return this.selectAs(sqlBuilderConsumer, fieldAlias);
    }

    return (C) this;
  }

  /**
   * 选择SQL字段
   *
   * @param fields SQL字段枚举
   * @return 具体实现
   */
  C selectEnum(Collection<Enum<?>> fields);

  /**
   * 选择SQL字段
   *
   * @param condition 条件
   * @param fields SQL字段枚举
   * @return 具体实现
   */
  default C selectEnum(boolean condition, Collection<Enum<?>> fields) {
    if (condition) {
      return this.selectEnum(fields);
    }

    return (C) this;
  }
}
